<?php

declare(strict_types=1);
/**
 * This file is part of habo_new_media.
 *
 * @link     https://www.berlen.cn/
 * @contact  tech@berlen.cn
 * @license  http://gitlab.rehou.cn/habo/habo_new_media/-/blob/master/README.md
 */
namespace app\service\token\media;

use app\enum\CommonEnum;
use app\enum\QqCodeEnum;
use app\enum\QqEnum;
use app\enum\TokenEnum;
use app\model\ClientAccountModel;
use app\service\client\AccountService;
use app\service\qq\FinanceService;
use app\service\token\MediaService;
use app\service\token\TokenInterface;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\facade\Cache;
use think\Model;

class QqService extends MediaService implements TokenInterface
{
    /**
     * 默认token值.
     */
    private const DEFAULT_TOKEN_VALUE = '1';

    protected int $mediaId = CommonEnum::QQ_MEDIA;

    /**
     * 获取媒体app-token.
     * @param int $status 状态
     */
    public function getMediaAppTokenList(int $status = 0): array
    {
        return TokenEnum::QQ_TOKEN_API_KEY_ARR;
    }

    /**
     * 获取value.
     * @param array $value token数据
     * @return false|string
     */
    public function getListValue(array $value = [])
    {
        return json_encode(['redis_key' => $value['redis_key'], 'media_id' => $this->mediaId, 'num' => $value['num']]);
    }

    /**
     * 获取token.
     * @param array $tokenData token数据
     */
    public function getToken(array $tokenData = []): string
    {
        return self::DEFAULT_TOKEN_VALUE;
    }

    /**
     * 获取token key.
     * @param array $tokenData token数据
     */
    public function getTokenKey(array $tokenData = []): string
    {
        return $tokenData['redis_key'];
    }

    /**
     * 获取媒体app-token分页.
     * @param int $status 状态 1正常  2失效
     * @return mixed
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function getMediaAppTokens(int $status = 0)
    {
        return AccountService::getAccountList($this->mediaId, $status);
    }

    /**
     * 根据refresh_token刷新token.
     * @param Model $model
     * @return bool
     */
    public function refreshToken(Model $model): bool
    {
        try {
            if (! $model instanceof ClientAccountModel && ! $model->getKey()) {
                return self::setError('账户信息不存在');
            }
            $redis = Cache::store('redis')->handler();
            $redisKey = $model->getAttr('advertiser_id') . TokenEnum::QQ_TOKEN;
            // 判断当前token有效期是否满足
            if ($redis->ttl($redisKey) >= rand(4500, 5500)) {
                return self::setError('token有效期充足，无需刷新');
            }
            $refreshKey = $this->getRefreshTokenKey($redisKey);
            $refreshToken = $redis->get($refreshKey);
            if (! $refreshToken) {
                return self::setError('refresh_token获取失败');
            }
            $paramsApi = [
                'client_id' => QqEnum::APP_ID,
                'client_secret' => QqEnum::APP_SECRET,
                'refresh_token' => $refreshToken,
            ];
            $res = FinanceService::refreshToken($paramsApi);
            if (empty($res)) {
                return self::setError('请求有误');
            }
            if ($res['code'] != QqCodeEnum::SUCCESS) {
                return self::setError($res['message']);
            }
            // 进redis
            $redis->set($redisKey, $res['data']['access_token'], $res['data']['access_token_expires_in']);
            $redis->set($refreshKey, $res['data']['refresh_token']);
            return true;
        } catch (\Exception $e) {
            return self::setError($e->getMessage());
        }
    }
}
